package maquinaV;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Stack;
import java.util.logging.Level;
import java.util.logging.Logger;
import GUI.Interfaz;
import java.text.DecimalFormat;

import javax.swing.JOptionPane;


public class MaquinaP {
    private int lineas=1;
    private String out="";
    private String ultimo[];
    int CProg;
    MemoriaDatos MemDat;
    Stack<String> Pila;
    ArrayList<TipoMemoria> heap;
    MemoriaInstrucciones Prog;
    int dirAlloc=0;
    boolean parada;
    boolean modoTraza;
    private String errores="";
    boolean hayErrores=false;

    public MaquinaP(ArrayList al,boolean modo){
    	CProg=0;
        ultimo=new String[2];
    	Prog=new MemoriaInstrucciones();
    	MemDat=new MemoriaDatos();
    	Pila= new Stack<String>();
        heap=new ArrayList<TipoMemoria>();
    	modoTraza=modo;
    	parada=false;
    	MemDat.cargarDatos(al);
    	Prog.cargaCod("codigop.txt");
    }
    public void ejecuta(){

        String s="";
	if(modoTraza==true){
            Instruccion inst=Prog.dameInstruccion(CProg);
            String Nombre=inst.getNombre();
            String Valor=inst.getValor();
            String Tipo=inst.getTipo();
            ejecutaInstruccion(Nombre,Valor,Tipo);
        }
        else {
        while(parada==false){
            Instruccion inst=Prog.dameInstruccion(CProg);
            String Nombre=inst.getNombre();
            String Valor=inst.getValor();
            String Tipo=inst.getTipo();
            ejecutaInstruccion(Nombre,Valor,Tipo);
   	}
        }
   }


   public ArrayList<String> muestraEstadoPila(){
	   ArrayList<String> estadoPila=new ArrayList<String>();
       System.out.println("Estado de la pila antes de la ejecucion de la instruccion:");
       if(Pila.size()>0){
           estadoPila.add(("Cima: "+Pila.elementAt(Pila.size()-1)).toString());
           for(int i=Pila.size()-2;i>=0;i--){
               estadoPila.add("     "+(Pila.elementAt(i)).toString());
           }
       }else{
           System.out.println("Pila vacia");
       }
      return estadoPila;
   }

   public ArrayList<String> muestraEstadoMemoria(){

       ArrayList<TipoMemoria> variables=MemDat.dameVariables();
       ArrayList<String> estadoMemoria=new ArrayList<String>();
       for(int i=0;i<variables.size();i++){
        estadoMemoria.add(variables.get(i).toString());
       }
       return estadoMemoria;
    }


   private void ejecutaInstruccion(String Nombre,String Valor,String Tipo){

	   if(Nombre.equals("apila_dir")){
		   apila_dir(Valor);
                    CProg++;

	   }
	   if(Nombre.equals("desapila_dir")){
		   desapila_dir(Valor);
                    CProg++;
	   }
	   if(Nombre.equals("apila")){
		   apila(Valor,Tipo);
                    CProg++;
	   }
           if(Nombre.equals("apila_ind")){
                  apila_ind();
                  CProg++;
           }
           if(Nombre.equals("desapila_ind")){
                  desapila_ind();
                  CProg++;
           }
           if(Nombre.equals("ir_a")){
                 ir_a(Integer.valueOf(Valor));
              
           }
           if(Nombre.equals("ir_f")){
                 ir_f(Integer.valueOf(Valor));
           }
           if(Nombre.equals("ir_v")){
                 ir_v(Integer.valueOf(Valor));
           }
           if(Nombre.equals("alloc")){
               alloc(Integer.valueOf(Valor));
               CProg++;
           }
           if(Nombre.equals("free")){
                free(Integer.valueOf(Valor));
                CProg++;
           }
           if(Nombre.equals("mueve")){
               mueve(Integer.valueOf(Valor));
               CProg++;
           }
	   if(Nombre.equals("ADD")||Nombre.equals("SUB")||Nombre.equals("MUL")||Nombre.equals("DIV")||Nombre.equals("MOD")){
		   OpAritmetica(Nombre);
                    CProg++;
	   }
	   if(Nombre.equals("in")||Nombre.equals("out")){
		   OpInOut(Nombre,Valor);
                    CProg++;
	   }
	   if(Nombre.equals("CASTING_E")||Nombre.equals("CASTING_R")){
		   OpCasting(Nombre);
                    CProg++;
	   }
	   if(Nombre.equals("ME")||Nombre.equals("MA")||Nombre.equals("MEI")||Nombre.equals("MAI")||Nombre.equals("IG")|Nombre.equals("NIG")){
		   OpComp(Nombre);
                    CProg++;
	   }
	   if(Nombre.equals("OR")||Nombre.equals("AND")||Nombre.equals("NOT")){
		    OpLog(Nombre);
                     CProg++;
	   }
       if(Nombre.equals("CS")){
	       OpCambioSigno();
                CProg++;
       }
	   if(Nombre.equals("STOP")){
	    	parada=true;
                 CProg++;
	   }
       if(Nombre.equals("duplicar")){
              duplica();
               CProg++;
       }

   }

  /*---------------------OPERACIONES PARA EL MANEJO DE LA PILA------------------------*/
   public void apila(String Valor,String Tipo){
       Pila.push(Valor+" "+Tipo);
       ultimo[0]=Valor;
       ultimo[1]=Tipo;
       lineas=1;
       if(Tipo.equals("0")&& !Valor.equals("NULL")) dirAlloc=Integer.valueOf(Valor);
  }

   public void duplica(){
       Pila.push(ultimo[0]+" "+ultimo[1]);
        lineas=1;
   }

   public void copia(){
       String dato=Pila.pop();
       Pila.push(dato);
       Pila.push(dato);
        lineas=1;
   }


   public void apila_dir(String dir){
       TipoMemoria dato=MemDat.dameValor(Integer.valueOf(dir));      
       Pila.push(dato.getValor()+" "+ dato.getTipo());
       ultimo[0]=dato.getValor();
       ultimo[1]=dato.getTipo();
        lineas=1;
   }

   public void desapila_dir(String dir){
       TipoMemoria t=MemDat.dameValor(Integer.valueOf(dir));
       
       String val[]=dameNumeroYTipo(Pila.pop());
       t.setValor(val[0]);
       //t.setTipo(val[1]);
       ultimo[0]=val[0];
       ultimo[1]=val[1];
       lineas=1;
  }

   /*Interpreta el valor d en la cima de la pila como un nÃºmero
      de celda en la memoria, y substituye dicho valor por el almacenado en dicha
      celda.*/
   public void apila_ind(){
       String s[]=dameNumeroYTipo(Pila.pop());
       TipoMemoria dato=MemDat.dameValor(Integer.valueOf(s[0]));
       Pila.push(dato.getValor()+" "+dato.getTipo());
       ultimo[0]=dato.getValor();
       ultimo[1]=dato.getTipo();
        lineas=1;
   }
   /*Desapila el valor de la cima  y la subcima , interpreta la subcima
     como un nÃºmero de celda en la memoria, y almacena la cima en dicha celda.*/
   public void desapila_ind(){
      String cima=Pila.pop();
       String subCima=Pila.pop();
      String[] scima=dameNumeroYTipo(cima);
      String[] ssubcima=dameNumeroYTipo(subCima);
      TipoMemoria dato;

      dato=MemDat.dameValor(Integer.valueOf(ssubcima[0]));
      dato.setValor(scima[0]);
      MemDat.setValor(Integer.valueOf(ssubcima[0]),dato);
       lineas=1;
     
    }

    /*---------------------OPERACIONES PARA EL CONTROL DE SALTOS------------------------*/

   public void ir_a(int i){
       int aux=CProg;
       CProg=i;
       //Pila.pop();
       lineas=CProg-aux;
   }

   public void ir_f(int i){
      String cima=Pila.pop();
      String s[]=dameNumeroYTipo(cima);
      if (s[0].equals("0")){
       int aux=CProg;
       CProg=i;
       lineas=CProg-aux;
      }
      else CProg++;
   }

   public void ir_v(int i){
      String cima=Pila.pop();
      String s[]=dameNumeroYTipo(cima);
      if (s[0].equals("1")){
       int aux=CProg;
       CProg=i;
       lineas=CProg-aux;
      }
      else CProg++;
   }
   
   /*-----------------------OPERACIONES AUXILIARES---------------------------------------*/
    public void mueve(int s){
        String cima=Pila.pop();
        String subcima=Pila.pop();
        String origen[]=dameNumeroYTipo(cima);
        String destino[]=dameNumeroYTipo(subcima);
        for(int i=0;i<s;i++){
            TipoMemoria orig=MemDat.dameValor(Integer.valueOf(origen[0])+i);
            MemDat.setValorAux(Integer.valueOf(destino[0])+i,orig.getValor());
        }
        
    }


    /*---------------------OPERACIONES PARA LA GESTION DE MEMORIA------------------------*/
    public void alloc(int t){
            int DirComienzo=MemDat.size();
            int cont=0;
            TipoMemoria tm=MemDat.dameValor(dirAlloc);
            String nombre=tm.getNombre();
            ArrayList<String> al=MemDat.dameTipos(nombre);
           /* for(int i=DirComienzo;i<DirComienzo+t;i++){
               TipoMemoria m=new TipoMemoria(" ","Reservado"," ");
               MemDat.add(m);
               cont++;
            }*/
            for(int i=0;i<al.size();i++){
                String s=al.get(i);
                if(s.equals("ent")){
                    TipoMemoria m=new TipoMemoria(nombre,"NULL","0");
                    MemDat.add(m);
                    cont++;
                }
                if(s.equals("real")){
                    TipoMemoria m=new TipoMemoria(nombre,"NULL","1");
                    MemDat.add(m);
                    cont++;
                }
                if(s.equals("puntero")){
                    TipoMemoria m=new TipoMemoria(nombre, "NULL","Puntero");
                    MemDat.add(m);
                    cont++;
                }
            }
            MemDat.setDirHeap(DirComienzo+cont);
            Pila.push(String.valueOf(DirComienzo));
    }
    public void free(int t){
          String[] s=dameNumeroYTipo(Pila.pop());
          int cont=0;
          for (int i=Integer.valueOf(s[0]);i<Integer.valueOf(s[0])+t;i++){
              MemDat.remove(i);
              cont++;
          }
          MemDat.setDirHeap(MemDat.getDirHeap()-cont);
    }



   public void OpAritmetica(String Nombre){

	      String val2=Pila.pop();
	      String val1=Pila.pop();
	      String[] sval1=dameNumeroYTipo(val1);
	      String[] sval2=dameNumeroYTipo(val2);

	      if (Nombre.equals("ADD")){
	         if(sval1[1].equals("Puntero")&&sval2[1].equals("0")){
                     Integer i= Integer.valueOf(sval1[0])+Integer.valueOf(sval2[0]);
	        	  Pila.push(String.valueOf(i)+" 0");
                          ultimo[0]=String.valueOf(i);
                          ultimo[1]="0";
                          lineas=1;
                 } 
                  if(sval1[1].equals("0")&&sval2[1].equals("0")){
	        	  Integer i= Integer.valueOf(sval1[0])+Integer.valueOf(sval2[0]);
	        	  Pila.push(String.valueOf(i)+" 0");
                          ultimo[0]=String.valueOf(i);
                          ultimo[1]="0";
                          lineas=1;
	          }
	          if(sval1[1].equals("0")&&sval2[1].equals("1")){
	        	  Double i= Double.valueOf(sval1[0])+Double.valueOf(sval2[0]);
	        	  Pila.push(String.valueOf(i)+" 1");
                          ultimo[0]=String.valueOf(i);
                          ultimo[1]="1";
                          lineas=1;
	          }
	          if(sval1[1].equals("1")&&sval2[1].equals("0")){
	        	  Double i= Double.valueOf(sval1[0])+Double.valueOf(sval2[0]);
	        	  Pila.push(String.valueOf(i)+" 1");
                  ultimo[0]=String.valueOf(i);
                  ultimo[1]="1";
                  lineas=1;
	          }
	         /* if(sval1[1]=="2"&&sval2[1]=="0"){
	        	  Integer i= Integer.valueOf(sval1[0])+Integer.valueOf(sval2[0]);
	        	  Pila.push(String.valueOf(i));
	          }
	          if(sval1[1]=="0"&&sval2[1]=="2"){
	        	  Integer i= Integer.valueOf(sval1[0])+Integer.valueOf(sval2[0]);
	        	  Pila.push(String.valueOf(i));
	          }*/
	          if(sval1[1].equals("1")&&sval2[1].equals("1")){
	        	  Double i= Double.valueOf(sval1[0])+Double.valueOf(sval2[0]);
	        	  Pila.push(String.valueOf(i)+" 1");
                  ultimo[0]=String.valueOf(i);
                  ultimo[1]="1";
                  lineas=1;
	          }
	      }
	      if (Nombre.equals("SUB")){
	          if(sval1[1].equals("0")&&sval2[1].equals("0")){
	        	  Integer i= Integer.valueOf(sval1[0])-Integer.valueOf(sval2[0]);
                  Pila.push(String.valueOf(i)+" 0");
                  ultimo[0]=String.valueOf(i);
                  ultimo[1]="1";
                  lineas=1;
	          }
	          if(sval1[1].equals("0")&&sval2[1].equals("1")){
	        	  Double i= Double.valueOf(sval1[0])-Double.valueOf(sval2[0]);
	        	  DecimalFormat p=new DecimalFormat("###########.##");
		          String s=p.format(i);
                  String aux=s.replace(",",".");

                  Pila.push(aux+" 1");
                  ultimo[0]=aux;
                  ultimo[1]="1";
                  lineas=1;
	          }
	          if(sval1[1].equals("1")&&sval2[1].equals("0")){
	        	  Double i= Double.valueOf(sval1[0])-Double.valueOf(sval2[0]);
	        	  DecimalFormat p=new DecimalFormat("###########.##");
		          String s=p.format(i);
                  String aux=s.replace(",",".");
                  Pila.push(aux+" 1");
                  ultimo[0]=aux;
                  ultimo[1]="1";
                  lineas=1;
	          }
	         /* if(sval1[1]=="2"&&sval2[1]=="0"){
	        	  Integer i= Integer.valueOf(sval1[0])-Integer.valueOf(sval2[0]);
	        	  Pila.push(String.valueOf(i));
	          }
	          if(sval1[1]=="0"&&sval2[1]=="2"){
	        	  Integer i= Integer.valueOf(sval1[0])-Integer.valueOf(sval2[0]);
	        	  Pila.push(String.valueOf(i));
	          }*/
	          if(sval1[1].equals("1")&&sval2[1].equals("1")){
	        	  Double i= Double.valueOf(sval1[0])-Double.valueOf(sval2[0]);
	        	  DecimalFormat p=new DecimalFormat("###########.##");
		          String s=p.format(i);
                  String aux=s.replace(",",".");

                  Pila.push(aux+" 1");
                  ultimo[0]=aux;
                  ultimo[1]="1";
                  lineas=1;
	          }
	      }
	       if (Nombre.equals("MUL")){
	          if(sval1[1].equals("0")&&sval2[1].equals("0")){
	        	  Integer i= Integer.valueOf(sval1[0])*Integer.valueOf(sval2[0]);
	        	  Pila.push(String.valueOf(i)+" 0");
                  ultimo[0]=String.valueOf(i);
                  ultimo[1]="0";
                  lineas=1;
	          }
	          if(sval1[1].equals("0")&&sval2[1].equals("1")){
	        	  Double i= Double.valueOf(sval1[0])*Double.valueOf(sval2[0]);
	        	  DecimalFormat p=new DecimalFormat("###########.##");
	        	  String s=p.format(i);
	        	  String aux=s.replace(",",".");
                  Pila.push(aux+" 1");
                  ultimo[0]=String.valueOf(i);
                  ultimo[1]="1";
                  lineas=1;
	          }
	          if(sval1[1].equals("1")&&sval2[1].equals("0")){
	        	  Double i= Double.valueOf(sval1[0])*Double.valueOf(sval2[0]);
	        	  DecimalFormat p=new DecimalFormat("###########.##");
	        	  String s=p.format(i);
	        	  String aux=s.replace(",",".");
                  Pila.push(aux+" 1");
                  ultimo[0]=String.valueOf(i);
                  ultimo[1]="1";
                  lineas=1;}
	         /* if(sval1[1]=="2"&&sval2[1]=="0"){
	        	  Integer i= Integer.valueOf(sval1[0])*Integer.valueOf(sval2[0]);
	        	  Pila.push(String.valueOf(i));
	          }
	          if(sval1[1]=="0"&&sval2[1]=="2"){
	        	  Integer i= Integer.valueOf(sval1[0])*Integer.valueOf(sval2[0]);
	        	  Pila.push(String.valueOf(i));
	          }*/
	          if(sval1[1].equals("1")&&sval2[1].equals("1")){
	        	  Double i= Double.valueOf(sval1[0])*Double.valueOf(sval2[0]);
	        	  DecimalFormat p=new DecimalFormat("###########.##");
                          String s=p.format(i);
                          String aux=s.replace(",",".");
                          Pila.push(aux+" 1");
                          ultimo[0]=String.valueOf(aux);
                          ultimo[1]="1";
                          lineas=1;
	          }
	      }

	      if (Nombre.equals("DIV")){
	    	  try{
	          if(sval1[1].equals("0")&&sval2[1].equals("0")){
	        	  int i= ((int)Integer.valueOf(sval1[0])/Integer.valueOf(sval2[0]));
	        	  Pila.push(String.valueOf(i)+" 0");
                  ultimo[0]=String.valueOf(i);
                  ultimo[1]="0";
                  lineas=1;
	          }
	          if(sval1[1].equals("0")&&sval2[1].equals("1")){
	        	  Double i= Double.valueOf(sval1[0])/Double.valueOf(sval2[0]);


	        	  if(!Double.isInfinite(i)){
	        		  DecimalFormat p=new DecimalFormat("###########.##");
		        	  String s=p.format(i);
		        	  String aux=s.replace(",",".");
                                  Pila.push(aux+" 1");
                                  ultimo[0]=String.valueOf(aux);
                                  ultimo[1]="1";
                                  lineas=1;
	        	  }
	        	  else{
	        		  errores=errores+"Error: division por cero, linea: "+String.valueOf(CProg+1)+"\n";
	        		  parada=true;
                      hayErrores=true;
	        	  }
	          }
	          if(sval1[1].equals("1")&&sval2[1].equals("0")){
	        	  Double i= Double.valueOf(sval1[0])/Double.valueOf(sval2[0]);	       	  //Pila.push(String.valueOf(i)+" 1");
	        	  if(!Double.isInfinite(i)&&!Double.isNaN(i)){
	        		  DecimalFormat p=new DecimalFormat("###########.##");
		        	  String s=p.format(i);
		        	  String aux=s.replace(",",".");
                                  Pila.push(aux+" 1");
                                  ultimo[0]=String.valueOf(aux);
                                  ultimo[1]="1";
                                  lineas=1;
	        	  }
	        	  else{
	        		  errores=errores+"Error: division por cero, linea: "+String.valueOf(CProg+1)+"\n";
	        		  parada=true;
                      hayErrores=true;
	        	  }

	          }
	         /* if(sval1[1]=="2"&&sval2[1]=="0"){
	        	  Integer i= Integer.valueOf(sval1[0])/Integer.valueOf(sval2[0]);
	        	  Pila.push(String.valueOf(i));
	          }
	          if(sval1[1]=="0"&&sval2[1]=="2"){
	        	  Integer i= Integer.valueOf(sval1[0])/Integer.valueOf(sval2[0]);
	        	  Pila.push(String.valueOf(i));
	          }*/
	          if(sval1[1].equals("1")&&sval2[1].equals("1")){
	        	  Double i= Double.valueOf(sval1[0])/Double.valueOf(sval2[0]);	       	  //Pila.push(String.valueOf(i)+" 1");
	        	  if(!Double.isInfinite(i)&&!Double.isNaN(i)){
	        		  DecimalFormat p=new DecimalFormat("###########.##");
		        	  String s=p.format(i);
                                 String aux=s.replace(",",".");
                                 Pila.push(aux+" 1");
                                 ultimo[0]=String.valueOf(aux);
                                 ultimo[1]="1";
                                 lineas=1;
	        	  }
	        	  else{
	        		  errores=errores+"Error: division por cero, linea: "+String.valueOf(CProg+1)+"\n";
	        		  parada=true;
                      hayErrores=true;
	        	  }

	          }
		      }
		      catch(ArithmeticException e){
		        	errores=errores+"Error: division por cero, linea: "+String.valueOf(CProg+1)+"\n";
		        	parada=true;
                    hayErrores=true;
		      }
		  }

	      if (Nombre.equals("MOD")){
	    	  try{
	    		  if(sval1[1].equals("0")&&sval2[1].equals("0")){
	 	        	  Integer i= Integer.valueOf(sval1[0])%Integer.valueOf(sval2[0]);
	 	        	  Pila.push(String.valueOf(i)+" 0");
                      ultimo[0]=String.valueOf(i);
                      ultimo[1]="0";
                      lineas=1;
	 	          }
	 	          else {
                                errores=errores+"Error: Los operandos del modulo no son de tipo entero, linea: "+String.valueOf(CProg+1)+"\n";
	 	            	parada=true;
                        hayErrores=true;
	 	         }
	 	     }
	 	     catch (ArithmeticException e){
                         errores=errores+"Error: Segundo operando de la operacion modulo es 0, linea: "+String.valueOf(CProg+1)+"\n";
	 	         parada=true;
                 hayErrores=true;
	 	     }
	 	 }
   }

   public void OpCasting(String nombre){
	   String val1=Pila.pop();
	   String[] sval1=dameNumeroYTipo(val1);
	   if(nombre.equals("CASTING_E")){
		  if (sval1[1].equals("0")){
		      Pila.push(sval1[0]+" "+sval1[1]);
              ultimo[0]=sval1[0];
              ultimo[1]=sval1[1];
              lineas=1;
		  }
		  else if (sval1[1].equals("1")){
			  Pila.push(String.valueOf((int)(Double.parseDouble(sval1[0])))+" 0");
              ultimo[0]=String.valueOf((int)(Double.parseDouble(sval1[0])));
              ultimo[1]="0";
              lineas=1;
		  }
	   }
	   if(nombre.equals("CASTING_R")){
		  if (sval1[1].equals("1")){
			  Pila.push(sval1[0]+" "+sval1[1]);
              ultimo[0]=sval1[0];
              ultimo[1]=sval1[1];
              lineas=1;
		  }
		  else if (sval1[1].equals("0")){
			  Pila.push(String.valueOf((double)(Integer.parseInt(sval1[0])))+" 1");
              ultimo[0]=String.valueOf((double)(Integer.parseInt(sval1[0])));
              ultimo[1]="1";
              lineas=1;
              }
	   }
   }

   public void OpInOut(String Nombre,String Tipo){
	   if (Nombre.equals("in")){
	    boolean valorCorrecto=false;
    	 String textoEnt= "Introduzca entero";
    	 String textoReal="Introduzca real";
	     while(!valorCorrecto){
	     if (Tipo.equals("REAL")){
	    	try{
	    	String var = JOptionPane.showInputDialog(textoReal, "");
	    	Double num= Double.parseDouble(var);
	    	valorCorrecto=true;
	    	Pila.push(var+" 1");
            ultimo[0]=var;
            ultimo[1]="1";
            lineas=1;
	    	}
	    	catch(Exception e){
	    		textoReal="No era un real";
                hayErrores=true;
	    	}

	     }

	     else if (Tipo.equals("ENT")){
	    	 try{
	    		 String var = JOptionPane.showInputDialog(textoEnt, "");
	    		 int num = Integer.parseInt(var);
	    		 valorCorrecto=true;
	    		 Pila.push(var+" 0");
                 ultimo[0]=var;
                 ultimo[1]="0";
                 lineas=1;
	    	 }
	    	 catch(Exception e)
	    	 {
	    		 textoEnt="No era un entero";
                 hayErrores=true;
	    	 }
	     }
	     }
	  }
	  else if (Nombre.equals("out")){
		  String[] s=dameNumeroYTipo(Pila.pop());
                  ultimo[0]=s[0];
                  ultimo[1]=s[1];
                  lineas=1;
		  out=out+s[0]+"\n";
      }

   }

   public void OpComp(String Nombre){
	   String val1=Pila.pop();
	   String[] sval1=dameNumeroYTipo(val1);
	   String val2=Pila.pop();
	   String[] sval2=dameNumeroYTipo(val2);

	   if(sval1[1].equals("0")&&sval2[1].equals("0")){
           if (Nombre.equals("IG")){
               if(Integer.valueOf(sval2[0])==Integer.valueOf(sval1[0])){
			   Pila.push("1 0");
		   }
		   else Pila.push("0 0");
           }
           if (Nombre.equals("NIG")){
               if(Integer.valueOf(sval2[0])!=Integer.valueOf(sval1[0])){
			   Pila.push("1 0");
		   }
		   else Pila.push("0 0");
           }

     	  if(Nombre.equals("ME")){
		  if(Integer.valueOf(sval2[0])<Integer.valueOf(sval1[0])){
			   Pila.push("1 0");
		   }
		   else Pila.push("0 0");
                  lineas=1;
     	  }
	   if(Nombre.equals("MA")){
		   if(Integer.valueOf(sval2[0])>Integer.valueOf(sval1[0])){
			   Pila.push("1 0");
		   }
		   else Pila.push("0 0");
                   lineas=1;
	   }
	   if(Nombre.equals("MEI")){
		   if(Integer.valueOf(sval2[0])<=Integer.valueOf(sval1[0])){
			   Pila.push("1 0");
		   }
		   else Pila.push("0 0");
                   lineas=1;
	   }
	   if(Nombre.equals("MAI")){
		   if(Integer.valueOf(sval2[0])>=Integer.valueOf(sval1[0])){
			   Pila.push("1 0");
		   }
		   else Pila.push("0 0");
                   lineas=1;
	   }
	   }

	   else{
                    if (Nombre.equals("IG")){
                         if(Double.valueOf(sval2[0])==Double.valueOf(sval1[0])){
			   Pila.push("1 0");
		   }
		   else Pila.push("0 0");
                    }
                    if (Nombre.equals("NIG")){
                     if(Double.valueOf(sval2[0])!=Double.valueOf(sval1[0])){
			   Pila.push("1 0");
		   }
		   else Pila.push("0 0");
           }
	     	  if(Nombre.equals("ME")){
			  if(Double.valueOf(sval2[0])<Double.valueOf(sval1[0])){
				   Pila.push("1 0");
			   }
			   else Pila.push("0 0");
                          lineas=1;
	     	  }
		   if(Nombre.equals("MA")){
			   if(Double.valueOf(sval2[0])>Double.valueOf(sval1[0])){
				   Pila.push("1 0");
			   }
			   else Pila.push("0 0");
                           lineas=1;
		   }
		   if(Nombre.equals("MEI")){
			   if(Double.valueOf(sval2[0])<=Double.valueOf(sval1[0])){
				   Pila.push("1 0");
			   }
			   else Pila.push("0 0");
                           lineas=1;
		   }
		   if(Nombre.equals("MAI")){
			   if(Double.valueOf(sval2[0])>=Double.valueOf(sval1[0])){
				   Pila.push("1 0");
			   }
			   else Pila.push("0 0");
                           lineas=1;
		   }
		   }
   }

   public void OpLog(String Nombre){

	      String val1=Pila.pop();
	      String[] sval1=dameNumeroYTipo(val1);


	      if (Nombre.equals("OR")){
	    	  String val2=Pila.pop();
	    	  String[] sval2=dameNumeroYTipo(val2);
	    	 if(sval1[1].equals("0")&&sval2[1].equals("0")){
	        	  if (Integer.valueOf(val1)==0 && Integer.valueOf(val1)==0){
	        		  Pila.push("0");
	        	  }
	        	  else Pila.push("1");
	          }
                  lineas=1;
          }

	      if (Nombre.equals("AND")){
	    	  String val2=Pila.pop();
	    	  String[] sval2=dameNumeroYTipo(val2);
	          if(sval1[1]=="0"&&sval2[1]=="0"){
	        	  if (Integer.valueOf(val1)==1 && Integer.valueOf(val1)==1)
	          	  Pila.push("1");
	          }
                  lineas=1;
	     }

	      if (Nombre.equals("NOT")){
	          if(sval1[1]=="0"){
	        	 if(Integer.valueOf(val1)==1){
	        	  	  Pila.push("0");
	             }
	        	 else if (Integer.valueOf(val1)==0){
	        		 Pila.push("1");
	        	 }
	          }
                  lineas=1;
	     }


   }

   public void OpCambioSigno(){
	   String val1=Pila.pop();
	   String[] sval1=dameNumeroYTipo(val1);
	   if(sval1[1].equals("0")){
           int aux= Integer.valueOf(sval1[0]);
           aux=-aux;
          Pila.push(String.valueOf(aux)+" "+sval1[1]);
       }
	   else if(sval1[1].equals("1")){
		Double aux=Double.valueOf(sval1[0]);
               aux=-aux;
                Pila.push(String.valueOf(aux)+" "+sval1[1]);
	   }
           lineas=1;
   }

   public String[] dameNumeroYTipo(String s){
       String []a;
       a=new String[2];
       a[0]="";a[1]="";
       a=s.split("\\s+");
       return a;
   }

   public MemoriaInstrucciones dameInstrucciones(){
       return Prog;
   }

   public String pilaToStrint(){
       String s="";
       String ret="";
       String []aux;
       for(int i=Pila.size();i>=1;i--){
           s=Pila.get(i-1).toString();
           aux=s.split("\\s");
           ret=ret+aux[0]+"\n";
       }
       return ret;
   }

    public int getCProg() {
        return CProg;
    }

   public String memoriaToString(){
       return MemDat.toString();
   }

   public String getOut(){
       return out;
   }
   public String getErrores(){return this.errores;}
   public boolean getHayErrores(){
       return hayErrores;
   }
   public boolean getParada(){
           return parada;
           }

   public int numLineas(){
       return lineas;
   }
}//fin de clase MaquinaP
